package com.rankeiot.core;

import com.jfinal.template.Engine;
import com.rankeiot.core.anno.aspect.DataScopeAspect;
import com.rankeiot.core.anno.aspect.RLockAspect;
import com.rankeiot.core.anno.aspect.RateLimitAspect;
import com.rankeiot.core.anno.interceptor.AuthInterceptor;
import com.rankeiot.core.anno.interceptor.OperationLogInterceptor;
import com.rankeiot.core.cache.*;
import com.rankeiot.core.dict.DataScope;

import com.rankeiot.core.dict.MenuType;
import com.rankeiot.core.dict.UserType;
import com.rankeiot.core.inner.QueryParamsMethodArgumentResolver;
import com.rankeiot.core.inner.ListMethodArgumentResolver;
import com.rankeiot.core.inner.PageQueryMethodArgumentResolver;
import com.rankeiot.core.job.JobManager;
import com.rankeiot.core.tags.JsonTag;
import com.rankeiot.core.util.LocaleUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.Primary;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;

import java.util.List;


@Configuration
@ComponentScan(basePackages = {"com.rankeiot.core.inner"})
@EnableConfigurationProperties(CacheConfig.class)
@EnableCaching
@Slf4j
public class EasyCorePlugin implements WebMvcConfigurer,Module, BeanFactoryPostProcessor, DisposableBean {
    public static boolean hasDataSource=false;
    public static boolean isDev=false;
    @Value("${spring.profiles.active:default}")
    private String active;
    @Value("${server.dev:false}")
    private boolean dev;


    /**
     * 是否为开发模式
     * @return
     */
    private boolean isDevModel(){

        return "dev".equals(active)||dev;
    }
    @Bean
    DataScopeAspect dataScopeAspect(){
        return new DataScopeAspect();
    }

//    @Bean
//    ICacheBuilder redissonCacheBuilder(){
//        return new RedissonCacheBuilder();
//    }
    @Bean
    @ConditionalOnMissingBean(value = ICacheBuilder.class)
    @ConditionalOnClass(Caffeine.class)
    ICacheBuilder cacheBuilder(){
        return new CaffeineCacheBuilder();
    }
    @Bean
    @Primary
    @ConditionalOnMissingBean(value = CacheManager.class)
    CacheManager cacheManager(CacheConfig cacheConfig,ICacheBuilder builder){
        return new CachesManager(cacheConfig,builder);
    }
    @Bean
    @ConditionalOnMissingBean(value = RLockAspect.LockManager.class)
    RLockAspect.LockManager lockManager(){
        return new RLockAspect.LocalLockManager();
    }
    @Bean
    RLockAspect rLockAspect(){
        return new RLockAspect();
    }
    @Bean
    RateLimitAspect rateLimitAspect(){
        return new RateLimitAspect();
    }
    @Bean
    JobManager jobManager(){
        return new JobManager();
    }
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(new PageQueryMethodArgumentResolver());
        resolvers.add(new ListMethodArgumentResolver());
        resolvers.add(new QueryParamsMethodArgumentResolver());
    }
    @Bean
    Engine enjoy(){
        Engine engine=Engine.use();
        if (isDevModel()){
            engine.setDevMode(true);
        }
        engine.setToClassPathSourceFactory();
        engine.setBaseTemplatePath("/templates/");
        try {
            engine.addDirective("json", JsonTag.class);
        }catch (Exception e){

        }
        return engine;
    }

    @Override
    public String name() {
        return "基础模块";
    }

    @Override
    public void start(ApplicationContext applicationContext){

        //注册全局ApplicationContext
        Context.applicationContext=applicationContext;

        //注册字典
        regFixedDict(DataScope.class);
        regFixedDict(UserType.class);
        regFixedDict(MenuType.class);

        //注册本地化插件
        new LocaleUtil(applicationContext);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        Context.beanFactory=beanFactory;
    }
//    @Bean("localeResolver")
//    public LocaleResolver localeResolver(){
////        AcceptHeaderLocaleResolver resolver=new AcceptHeaderLocaleResolver();
////        resolver.setDefaultLocale(Locale.getDefault());
//        CookieLocaleResolver resolver=new CookieLocaleResolver("lang");
//        resolver.setDefaultLocale(Locale.getDefault());
//        return resolver;
//    }
//    @Bean
//    public MessageSource messageSource(){
//      // ReloadableResourceBundleMessageSource messageSource=new ReloadableResourceBundleMessageSource();
//        ResourceBundleMessageSource messageSource=new ResourceBundleMessageSource();
//
//        messageSource.setBasename("i18n/messages");
//        messageSource.setDefaultEncoding("UTF-8");
//        messageSource.setFallbackToSystemLocale(true);
//        return messageSource;
//    }
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/**");
        registry.addInterceptor(new OperationLogInterceptor(Context.applicationContext)).addPathPatterns("/**");
        //语言
        LocaleChangeInterceptor localeInterceptor = new LocaleChangeInterceptor();
        localeInterceptor.setParamName("lang");  //拦截lang参数
        registry.addInterceptor(localeInterceptor);

    }

    @Override
    public void destroy() throws Exception {
        log.info("Core模块销毁");
        MenuManager.getGroupMenus().clear();
        Config.configMap().clear();
        Config.configService=null;
        Current.setUserLoader(null);
       // Current.invalidateAllUser();
        Current._allUsers=null;
        Context.applicationContext=null;
        Context.beanFactory=null;
    }
    /**
   // @Override
    public void start(AopContext aopContext) {

        JobManager.start(aopContext);
    }

**/

}
